package com.treasure.service.listener.process;

import com.alibaba.fastjson.JSON;
import com.treasure.service.collocate.service.GainStatisticsService;
import com.treasure.service.commons.lang.util.IdCreater;
import com.treasure.service.commons.lang.util.StringUtil;
import com.treasure.service.constant.Constants;
import com.treasure.service.domain.*;
import com.treasure.service.enums.GainEnum;
import com.treasure.service.mapper.TApplyCardOrderMapper;
import com.treasure.service.mapper.TRebateConfigMapper;
import com.treasure.service.mapper.TUserInfoMapper;
import com.treasure.service.mapper.TallyLogMapper;
import com.treasure.service.third.utils.RestClient;
import com.treasure.service.user.service.UserInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
* @Description:    处理信用卡办理结果事务
* @Author:         panxinwen
* @CreateDate:     2018/11/4 10:35
* @Version:        1.0
*/
@Component
public class CreditCardScheduleProcess {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${treasure.rest.service.pay}")
    private String thirdUrl;

    @Autowired
    private TApplyCardOrderMapper tApplyCardOrderMapper;

    @Autowired
    private TRebateConfigMapper tRebateConfigMapper;

    @Autowired
    private TUserInfoMapper tUserInfoMapper;

    @Autowired
    private TallyLogMapper tallyLogMapper;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private GainStatisticsService gainStatisticsService;

    @Autowired
    private RestClient restClient;

    //办理成功处理
    @Transactional(rollbackFor = Exception.class)
    public void  process(Long orderId,Integer result){

        try {
            TApplyCardOrder tApplyCardOrder = tApplyCardOrderMapper.selectByPrimaryKey(orderId);

            if (tApplyCardOrder == null || tApplyCardOrder.getId() == null){
                logger.info("信用卡办理成功处理,未找到对应的订单信息：orderId{}",orderId);
                return;
            }

            //第一步更新订单状态
            tApplyCardOrder.setId(orderId);
            tApplyCardOrder.setStatus(result);
            tApplyCardOrderMapper.updateByPrimaryKeySelective(tApplyCardOrder);

            //第二步如果成功计算返佣-包括自己的返佣及邀请人的返佣
            if (result == 1){
                calculateMineCommission(tApplyCardOrder);
            }
        } catch (Exception e) {
           logger.error("信用卡办理结果处理异常：order={},error={}",orderId,e);
        }
    }


    //计算返佣
    private void calculateMineCommission(TApplyCardOrder tApplyCardOrder) throws Exception {

        TRebateConfig tRebateConfig = tRebateConfigMapper.selectOne(new TRebateConfig());

        //Todo 查询自己的信息
        Long userId = tApplyCardOrder.getCustomerId();
        TUserInfo tUserInfo = tUserInfoMapper.selectByPrimaryKey(userId);
        logger.info("查询当前会员等级：userId{},grade{}",userId,tUserInfo.getGrade());

        Long commission = tApplyCardOrder.getCommission();//Todo 基础返佣金额
        logger.info("计算用户返佣金额order{}，基础返佣金额{}",tApplyCardOrder.getId(),commission);
        Long amt=0l;
        //Todo 计算自己的返佣
        switch (tUserInfo.getGrade()){
            case 0://普通会员
                amt=tRebateConfig.getuApplyCardRate();
                break;
            case 1://计算付费会员返佣
                amt=tRebateConfig.getvApplyCardRate();
                break;
            case 2://创业者
                amt=tRebateConfig.getfApplyCardRate();
                break;
            case 3://创业家
                amt=tRebateConfig.getGfApplyCardRate();
                break;
            default :
                amt=0l;
                break;

        }

        Long ultimately = commission*amt/100;
        TallyLog tallyLog = new TallyLog();
        logger.info("计算自己的返佣金额为order={},ultimately={}",tApplyCardOrder.getId(),ultimately);
        //Todo 记账
        tallyLog.setId(IdCreater.getLongId());
        tallyLog.setAcquireId(userId);
        tallyLog.setAmount(ultimately);
        tallyLog.setAppointAmount(commission);
        tallyLog.setAppointApr(amt);
        tallyLog.setCreateTime(new Date());
        tallyLog.setModifyTime(new Date());
        tallyLog.setOrderId(tApplyCardOrder.getId());
        tallyLog.setType(Constants.InviteType.CTRANSACTION__CARD_ONESELF);
        tallyLog.setUserId(userId);
        tallyLog.setAcquireGrade(tUserInfo.getGrade());

        //Todo 更新今日自己办卡返佣金额统计
        gainStatisticsService.calculatePrice(userId,GainEnum.APPLY_CARD.getCode(),tallyLog.getAmount());

        //Todo 方消息给用户(公众号及短信)
        

        //Todo 邀请人返佣计算
        if (amt == 0){
            calculateFather(userId,tRebateConfig, tApplyCardOrder,tallyLog);
        }

    }

    //Todo 计算邀请人奖励金额
    private void calculateFather(Long userId,TRebateConfig tRebateConfig,TApplyCardOrder tApplyCardOrder,TallyLog tallyLog) throws Exception {

        //Todo 查询父级邀请人
        TUserInfo tUserInfo = tUserInfoMapper.selectByPrimaryKey(userId);
        Long inviteCode = tUserInfo.getInviteCode();
        Long commission = tApplyCardOrder.getCommission();//Todo 基础返佣金额
        if (StringUtil.isNotEmpty(inviteCode)){

          TUserInfo fUserInfo = tUserInfoMapper.selectByPrimaryKey(inviteCode);
          Long amt=0l;
          if (fUserInfo != null && fUserInfo.getUserId() != null){

              tallyLog.setFatherId(fUserInfo.getUserId());
              tallyLogMapper.insert(tallyLog);
              //Todo 判断返佣比例
              switch (tUserInfo.getGrade()){
                  case 0://没有返佣
                      amt=tRebateConfig.getuInviteCardRate();
                      break;
                  case 1://计算付费会员返佣
                      amt=tRebateConfig.getvInviteCardRate();
                      break;
                  case 2://创业者
                      amt=tRebateConfig.getfInviteCardRate();
                      break;
                  case 3://创业家
                      amt=tRebateConfig.getGfInviteCardRate();
                      break;
                  default :
                      amt=0l;
                      break;

              }

              Long ultimately = commission*amt/100;
              logger.info("计算邀请人返佣金额为order={},ultimately={}",tApplyCardOrder.getId(),ultimately);
              //Todo 记账
              TallyLog fatherTallyLog = new TallyLog();
              fatherTallyLog.setId(IdCreater.getLongId());
              fatherTallyLog.setAcquireId(fUserInfo.getUserId());
              fatherTallyLog.setAmount(ultimately);
              fatherTallyLog.setAppointAmount(commission);
              fatherTallyLog.setAppointApr(amt);
              fatherTallyLog.setCreateTime(new Date());
              fatherTallyLog.setModifyTime(new Date());
              fatherTallyLog.setOrderId(tApplyCardOrder.getId());
              fatherTallyLog.setType(32);
              fatherTallyLog.setUserId(tallyLog.getUserId());
              fatherTallyLog.setAcquireGrade(fUserInfo.getGrade());
              gainStatisticsService.calculatePrice(userId,GainEnum.INVITE_CARD.getCode(),tallyLog.getAmount());
              calculateTop(fUserInfo.getUserId(),tRebateConfig,ultimately,tApplyCardOrder,fatherTallyLog);
          }
        }
        logger.info("获得办卡返利：{}",JSON.toJSONString(tallyLog));
        tallyLogMapper.insert(tallyLog);
        tally(tallyLog.getType(),tallyLog.getAmount(),tallyLog.getAcquireId(),tallyLog.getId());
        userInfoService.statisticsIntegral(tallyLog.getAmount(),tallyLog.getUserId(),Constants.TreasurePrice.EARN_EARNINGS);

    }

    //Todo 顶级邀请人返佣
    private void calculateTop(Long userId,TRebateConfig tRebateConfig,Long amount,TApplyCardOrder tApplyCardOrder,TallyLog fatherTallyLog) throws Exception {

        //Todo 查询父级邀请人
        TUserInfo tUserInfo = tUserInfoMapper.selectByPrimaryKey(userId);
        Long inviteCode = tUserInfo.getInviteCode();
        Long commission = tApplyCardOrder.getCommission();//Todo 基础返佣金额
        if (StringUtil.isNotEmpty(inviteCode)){
          TUserInfo fUserInfo = tUserInfoMapper.selectByPrimaryKey(inviteCode);
          Long amt=0l;
          if (fUserInfo != null && fUserInfo.getUserId() != null){
              fatherTallyLog.setFatherId(fUserInfo.getUserId());
              //Todo 判断返佣比例
              switch (tUserInfo.getGrade()){
                  case 0://没有返佣
                      amt=tRebateConfig.getuShareCardRate();
                      break;
                  case 1://计算付费会员返佣
                      amt=tRebateConfig.getvShareCardRate();
                      break;
                  case 2://创业者
                      amt=tRebateConfig.getfShareCardRate();
                      break;
                  case 3://创业家
                      amt=tRebateConfig.getGfShareCardRate();
                      break;
                  default :
                      amt=0l;
                      break;

              }
              Long ultimately = (commission-amount)*amt/100;
              logger.info("计算顶级邀请人的返佣金额为order={},ultimately={}",tApplyCardOrder.getId(),ultimately);
              //Todo 记账
              TallyLog topTallyLog = new TallyLog();
              topTallyLog.setId(IdCreater.getLongId());
              topTallyLog.setAcquireId(fUserInfo.getUserId());
              topTallyLog.setAmount(ultimately);
              topTallyLog.setAppointAmount(commission);
              topTallyLog.setAppointApr(amt);
              topTallyLog.setCreateTime(new Date());
              topTallyLog.setModifyTime(new Date());
              topTallyLog.setOrderId(tApplyCardOrder.getId());
              topTallyLog.setType(33);
              topTallyLog.setUserId(fatherTallyLog.getUserId());
              topTallyLog.setAcquireGrade(fUserInfo.getGrade());
              gainStatisticsService.calculatePrice(fUserInfo.getUserId(),GainEnum.SHARE_CARD.getCode(),topTallyLog.getAmount());
              logger.info("顶级邀请者获得办卡返利：{}",JSON.toJSONString(topTallyLog));

              tallyLogMapper.insert(topTallyLog);
              tally(topTallyLog.getType(),topTallyLog.getAmount(),topTallyLog.getAcquireId(),topTallyLog.getId());
              userInfoService.statisticsIntegral(topTallyLog.getAmount(),topTallyLog.getUserId(),Constants.TreasurePrice.EARN_EARNINGS);

          }
        }
        logger.info("父级邀请者获得办卡返利：{}",JSON.toJSONString(fatherTallyLog));
        tallyLogMapper.insert(fatherTallyLog);
        tally(fatherTallyLog.getType(),fatherTallyLog.getAmount(),fatherTallyLog.getAcquireId(),fatherTallyLog.getId());
        userInfoService.statisticsIntegral(fatherTallyLog.getAmount(),fatherTallyLog.getUserId(),Constants.TreasurePrice.EARN_EARNINGS,Constants.TreasurePrice.CHILD_CTRANSACTION_CARD);

    }

    private void  tally(Integer type,Long amount,Long userId,Long orderId) throws Exception {

        Map<String,String> map = new HashMap<>();
        map.put("type",type+"");
        map.put("amount",amount+"");
        map.put("userId",userId+"");
        map.put("orderId",orderId+"");

        Integer result = restClient.post(thirdUrl+"/tally/v1/tally",map,Integer.class);

        if (result != 1){
            throw new Exception();
        }

    }


    public class CommissionCalculate {

        Long commission;//基础返佣金额
        TRebateConfig config;//返佣比例
        Integer grade;//会员等级
        Long ultimately;//本次获取到的佣金

        public void setCommission(Long commission,TRebateConfig config,Integer grade) {
            this.commission = commission;
            this.config=config;
            this.grade=grade;
        }

//        public void calculate(){
//
//            ultimately = commission*amt/100;
//
//        }

    }

}
